using FluentMigrator;

namespace AuthService.Infrastructure.Migrations;

/// <summary>
/// 创建动态API端点表的数据库迁移
/// 版本号：20241214002 (格式：YYYYMMDDNNN)
/// 支持运行时配置和管理API端点，实现动态路由功能
/// 包含权限控制、性能配置、请求转换等高级功能
/// </summary>
[Migration(20241214002)] // 迁移版本号，必须大于前一个迁移的版本号
public class CreateDynamicApiEndpointsTable : Migration
{
    /// <summary>
    /// 执行向上迁移 - 创建DynamicApiEndpoints表及其索引
    /// 此表用于存储动态API端点配置，支持运行时路由管理
    /// </summary>
    public override void Up()
    {
        // 创建动态API端点表
        Create.Table("DynamicApiEndpoints")
            // === 基础标识字段 ===
            .WithColumn("Id").AsGuid().PrimaryKey("PK_DynamicApiEndpoints") // 主键
            .WithColumn("Name").AsString(100).NotNullable() // 端点名称，用于标识和管理
            .WithColumn("Description").AsString(500).Nullable() // 端点描述，可为空

            // === HTTP配置字段 ===
            .WithColumn("Method").AsInt32().NotNullable() // HTTP方法枚举值 (GET=0, POST=1, PUT=2, DELETE=3等)
            .WithColumn("PathTemplate").AsString(500).NotNullable() // 路径模板，支持参数占位符如 /api/users/{id}
            .WithColumn("TargetService").AsString(100).Nullable() // 目标服务名称，用于服务发现
            .WithColumn("TargetUrl").AsString(1000).Nullable() // 目标URL，直接指定转发地址

            // === 状态和权限控制字段 ===
            .WithColumn("IsEnabled").AsBoolean().NotNullable().WithDefaultValue(true) // 端点启用状态
            .WithColumn("RequireAuthentication").AsBoolean().NotNullable().WithDefaultValue(true) // 是否需要身份验证
            .WithColumn("RequiredRoles").AsString(2000).NotNullable().WithDefaultValue("[]") // 所需角色，JSON数组格式
            .WithColumn("RequiredPermissions").AsString(2000).NotNullable().WithDefaultValue("[]") // 所需权限，JSON数组格式

            // === 性能和限制配置字段 ===
            .WithColumn("RateLimitPerMinute").AsInt32().Nullable() // 每分钟请求限制，null表示无限制
            .WithColumn("TimeoutSeconds").AsInt32().NotNullable().WithDefaultValue(30) // 请求超时时间（秒）
            .WithColumn("RetryCount").AsInt32().NotNullable().WithDefaultValue(0) // 重试次数
            .WithColumn("CacheSeconds").AsInt32().NotNullable().WithDefaultValue(0) // 缓存时间（秒），0表示不缓存

            // === 请求/响应配置字段（JSON格式存储） ===
            .WithColumn("Headers").AsString(4000).NotNullable().WithDefaultValue("{}") // 自定义HTTP头，JSON对象格式
            .WithColumn("QueryParameters").AsString(4000).NotNullable().WithDefaultValue("{}") // 查询参数配置，JSON对象格式
            .WithColumn("RequestTransformation").AsString(8000).Nullable() // 请求转换规则，JSON格式
            .WithColumn("ResponseTransformation").AsString(8000).Nullable() // 响应转换规则，JSON格式

            // === 版本和分类管理字段 ===
            .WithColumn("Version").AsString(20).NotNullable().WithDefaultValue("1.0") // API版本号
            .WithColumn("Tags").AsString(2000).NotNullable().WithDefaultValue("[]") // 标签，JSON数组格式，用于分类和搜索
            .WithColumn("TenantId").AsString(50).Nullable() // 租户ID，支持多租户隔离
            .WithColumn("Priority").AsInt32().NotNullable().WithDefaultValue(0) // 优先级，数值越大优先级越高

            // === 扩展和统计字段 ===
            .WithColumn("Metadata").AsString(4000).Nullable() // 元数据，JSON格式存储扩展信息
            .WithColumn("LastAccessedAt").AsDateTime().Nullable() // 最后访问时间
            .WithColumn("AccessCount").AsInt64().NotNullable().WithDefaultValue(0) // 访问计数

            // === 审计字段（继承自基础审计模式） ===
            .WithColumn("CreatedAt").AsDateTime().NotNullable().WithDefaultValue(SystemMethods.CurrentUTCDateTime) // 创建时间
            .WithColumn("UpdatedAt").AsDateTime().NotNullable().WithDefaultValue(SystemMethods.CurrentUTCDateTime) // 更新时间
            .WithColumn("CreatedBy").AsString(50).Nullable() // 创建者
            .WithColumn("UpdatedBy").AsString(50).Nullable() // 更新者
            .WithColumn("IsDeleted").AsBoolean().NotNullable().WithDefaultValue(false) // 软删除标记
            .WithColumn("DeletedAt").AsDateTime().Nullable() // 删除时间
            .WithColumn("DeletedBy").AsString(50).Nullable(); // 删除者

        // === 创建唯一约束和索引 ===

        // 唯一约束：确保同一租户下的路径模板和HTTP方法组合唯一
        // 这防止了重复的路由配置，确保路由解析的唯一性
        Create.Index("UQ_DynamicApiEndpoints_TenantId_PathTemplate_Method")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("TenantId").Ascending() // 租户ID
            .OnColumn("PathTemplate").Ascending() // 路径模板
            .OnColumn("Method").Ascending() // HTTP方法
            .WithOptions().Unique(); // 设置为唯一约束

        // === 基础查询性能索引 ===

        // 状态查询索引 - 用于查询启用且未删除的端点
        Create.Index("IX_DynamicApiEndpoints_IsEnabled_IsDeleted")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("IsEnabled").Ascending()
            .OnColumn("IsDeleted").Ascending();

        // 租户隔离索引 - 用于多租户环境下的数据隔离
        Create.Index("IX_DynamicApiEndpoints_TenantId")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("TenantId")
            .Ascending();

        // HTTP方法索引 - 用于按请求方法过滤端点
        Create.Index("IX_DynamicApiEndpoints_Method")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("Method")
            .Ascending();

        // 路径模板索引 - 用于路由匹配和查找
        Create.Index("IX_DynamicApiEndpoints_PathTemplate")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("PathTemplate")
            .Ascending();

        // 目标服务索引 - 用于按服务名称查询端点
        Create.Index("IX_DynamicApiEndpoints_TargetService")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("TargetService")
            .Ascending();

        // 优先级索引 - 用于按优先级排序（高优先级在前）
        Create.Index("IX_DynamicApiEndpoints_Priority")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("Priority")
            .Descending(); // 降序，优先级高的在前

        // === 时间和统计相关索引 ===

        // 创建时间索引 - 用于按创建时间排序
        Create.Index("IX_DynamicApiEndpoints_CreatedAt")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("CreatedAt")
            .Descending(); // 降序，最新的在前

        // 最后访问时间索引 - 用于查询最近使用的端点
        Create.Index("IX_DynamicApiEndpoints_LastAccessedAt")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("LastAccessedAt")
            .Descending(); // 降序，最近访问的在前

        // 访问计数索引 - 用于查询热门端点
        Create.Index("IX_DynamicApiEndpoints_AccessCount")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("AccessCount")
            .Descending(); // 降序，访问量高的在前

        // === 复合索引（多列组合索引，优化复杂查询） ===

        // 多租户管理复合索引 - 优化租户级别的端点管理查询
        // 适用场景：查询特定租户下启用的、未删除的端点，并按优先级排序
        Create.Index("IX_DynamicApiEndpoints_TenantId_IsEnabled_IsDeleted_Priority")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("TenantId").Ascending() // 先按租户分组
            .OnColumn("IsEnabled").Ascending() // 再按启用状态
            .OnColumn("IsDeleted").Ascending() // 然后按删除状态
            .OnColumn("Priority").Descending(); // 最后按优先级降序

        // 路由匹配复合索引 - 优化API网关的路由解析性能
        // 适用场景：根据HTTP方法和路径模板快速找到启用的端点
        // 这是API网关最常用的查询模式
        Create.Index("IX_DynamicApiEndpoints_Method_PathTemplate_IsEnabled")
            .OnTable("DynamicApiEndpoints")
            .OnColumn("Method").Ascending() // HTTP方法
            .OnColumn("PathTemplate").Ascending() // 路径模板
            .OnColumn("IsEnabled").Ascending(); // 启用状态
    }

    /// <summary>
    /// 执行向下迁移 - 删除DynamicApiEndpoints表
    /// 当执行回滚操作时会调用此方法
    /// 注意：这会删除整个表及其所有数据和索引，请谨慎使用
    /// </summary>
    public override void Down()
    {
        // 删除整个DynamicApiEndpoints表
        // FluentMigrator会自动处理相关的索引、约束和外键的删除
        Delete.Table("DynamicApiEndpoints");
    }
}
